#include "frame_statistics.h"
#include <numeric>
#include <cmath>
#include <algorithm>
#include <stdexcept>

// 构造函数
FrameStatistics::FrameStatistics(std::chrono::seconds window_duration)
    : window_duration_(window_duration),
      current_window_start_(std::chrono::system_clock::now()) {}

// 计算标准差
double FrameStatistics::calculateStandardDeviation(const std::vector<double>& values, double mean) {
    if (values.size() <= 1) return 0.0;
    
    double sum_sq_diff = 0.0;
    for (double val : values) {
        sum_sq_diff += std::pow(val - mean, 2);
    }
    
    return std::sqrt(sum_sq_diff / (values.size() - 1));
}

// 检查是否需要创建新的统计窗口
bool FrameStatistics::shouldCreateNewWindow() {
    auto now = std::chrono::system_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - current_window_start_);
    return elapsed >= window_duration_;
}

// 重置当前窗口
void FrameStatistics::resetCurrentWindow() {
    frames_.clear();
    frame_intervals_.clear();
    current_window_start_ = std::chrono::system_clock::now();
}

// 添加帧到统计窗口
void FrameStatistics::addFrame(std::shared_ptr<VideoFrame> frame) {
    if (!frame) return;
    
    std::lock_guard<std::mutex> lock(data_mutex_);
    
    // 计算与上一帧的间隔
    if (!frames_.empty()) {
        auto last_frame = frames_.back();
        auto interval = std::chrono::duration_cast<std::chrono::microseconds>(
            frame->getCaptureTime() - last_frame->getCaptureTime()
        );
        frame_intervals_.push_back(interval.count() / 1000.0); // 转换为毫秒
    }
    
    frames_.push_back(frame);
}

// 强制计算当前窗口的统计数据并重置窗口
FrameStatisticsData FrameStatistics::calculateAndReset() {
    std::lock_guard<std::mutex> lock(data_mutex_);
    
    FrameStatisticsData stats;
    if (frames_.empty()) {
        stats.window_start = current_window_start_;
        stats.window_end = std::chrono::system_clock::now();
        return stats;
    }
    
    // 窗口时间
    stats.window_start = current_window_start_;
    stats.window_end = std::chrono::system_clock::now();
    
    // 总帧数和总数据量
    stats.total_frames = frames_.size();
    for (const auto& frame : frames_) {
        stats.total_data_size += frame->getFrameSize();
    }
    
    // 计算窗口持续时间（秒）
    auto window_duration = std::chrono::duration_cast<std::chrono::seconds>(
        stats.window_end - stats.window_start
    ).count();
    if (window_duration <= 0) window_duration = 1; // 避免除以零
    
    // 帧率统计 (fps)
    stats.avg_frame_rate = static_cast<double>(stats.total_frames) / window_duration;
    
    // 码率统计 (Kbps)
    // 1字节 = 8比特, 1KB = 1024字节, 1Kbps = 1000比特/秒
    stats.avg_bitrate = (static_cast<double>(stats.total_data_size) * 8.0) / 
                       (window_duration * 1000.0);
    
    // 帧间隔统计
    if (!frame_intervals_.empty()) {
        double sum_interval = std::accumulate(frame_intervals_.begin(), frame_intervals_.end(), 0.0);
        stats.avg_interval = sum_interval / frame_intervals_.size();
        stats.std_dev_interval = calculateStandardDeviation(frame_intervals_, stats.avg_interval);
    }
    
    // 帧大小统计
    std::vector<double> frame_sizes;
    for (const auto& frame : frames_) {
        size_t size = frame->getFrameSize();
        frame_sizes.push_back(static_cast<double>(size));
        stats.min_frame_size = std::min(stats.min_frame_size, size);
        stats.max_frame_size = std::max(stats.max_frame_size, size);
    }
    
    if (!frame_sizes.empty()) {
        double sum_size = std::accumulate(frame_sizes.begin(), frame_sizes.end(), 0.0);
        stats.avg_frame_size = sum_size / frame_sizes.size();
        stats.std_dev_frame_size = calculateStandardDeviation(frame_sizes, stats.avg_frame_size);
    }
    
    // 各阶段延迟统计
    std::map<FrameStage, std::vector<double>> stage_latencies;
    
    for (const auto& frame : frames_) {
        // 采集到编码的延迟
        double capture_encode = frame->getCaptureToEncodeLatency();
        stage_latencies[FrameStage::CAPTURE].push_back(capture_encode);
        
        // 编码到发送的延迟
        double encode_send = frame->getEncodeToSendLatency();
        stage_latencies[FrameStage::ENCODE].push_back(encode_send);
        
        // 发送到接收的延迟
        double send_receive = frame->getSendToReceiveLatency();
        stage_latencies[FrameStage::SEND].push_back(send_receive);
        
        // 接收到解码的延迟
        double receive_decode = frame->getReceiveToDecodeLatency();
        stage_latencies[FrameStage::RECEIVE].push_back(receive_decode);
        
        // 解码到渲染的延迟
        double decode_render = frame->getDecodeToRenderLatency();
        stage_latencies[FrameStage::DECODE].push_back(decode_render);
        
        // 端到端延迟
        double end_to_end = frame->getEndToEndLatency();
        stage_latencies[FrameStage::RENDER].push_back(end_to_end);
    }
    
    // 计算各阶段的统计值
    for (const auto& [stage, latencies] : stage_latencies) {
        if (latencies.empty()) continue;
        
        StageStatistics stage_stats;
        stage_stats.frame_count = latencies.size();
        
        // 平均值
        double sum = std::accumulate(latencies.begin(), latencies.end(), 0.0);
        stage_stats.avg_latency = sum / latencies.size();
        
        // 最小值和最大值
        auto [min_it, max_it] = std::minmax_element(latencies.begin(), latencies.end());
        stage_stats.min_latency = *min_it;
        stage_stats.max_latency = *max_it;
        
        // 标准差
        stage_stats.std_dev_latency = calculateStandardDeviation(latencies, stage_stats.avg_latency);
        
        stats.stage_stats[stage] = stage_stats;
    }
    
    // 端到端延迟单独统计
    if (stage_latencies.count(FrameStage::RENDER)) {
        const auto& e2e_latencies = stage_latencies[FrameStage::RENDER];
        stats.avg_end_to_end = std::accumulate(e2e_latencies.begin(), e2e_latencies.end(), 0.0) / e2e_latencies.size();
        
        auto [min_it, max_it] = std::minmax_element(e2e_latencies.begin(), e2e_latencies.end());
        stats.min_end_to_end = *min_it;
        stats.max_end_to_end = *max_it;
        
        stats.std_dev_end_to_end = calculateStandardDeviation(e2e_latencies, stats.avg_end_to_end);
    }
    
    // 重置窗口
    resetCurrentWindow();
    
    return stats;
}
